package collection

import (
	"iter"

	"gitee.com/gousing/helper/jsoner"
)

// Queue 使用Slice实现的简单队列（无锁, 不适用于并发场景）
// 队列先进先出，与栈操作顺序相反
type Queue[T any] struct {
	data []T // 底层切片
	size int // 队列的元素数量
}

func NewQueue[T any]() *Queue[T] {
	return new(Queue[T])
}

// Push 入队
func (s *Queue[T]) Push(val ...T) {
	l := len(val)
	if l > 0 {
		s.size = s.size + l
		s.data = append(s.data, val...)
	}
}

// Pop 出队，队列最前面元素, 并移除队列数据
func (s *Queue[T]) Pop() (val T, ok bool) {
	// 队列已空
	if s.size == 0 {
		return
	}
	// 队列最前面元素
	val = s.data[0]
	ok = true
	s.data = s.data[1:]
	//队列中元素数量-1
	s.size--
	return
}

// Top 返回队列最前面元素 但是不移除队列数据
func (s *Queue[T]) Peak() (val T, ok bool) {
	// 队列元素已空
	if s.size == 0 {
		return
	}
	// 队列元素
	val = s.data[0]
	ok = true
	return
}

// Size 队列中元素数量
func (s *Queue[T]) Size() int {
	return s.size
}

// IsEmpty 队列是否为空
func (s *Queue[T]) IsEmpty() bool {
	return s.size == 0
}

// Iter 队列数据迭代器(不消费数据)
//   - for v := range queueSync.Iter() {}
func (s *Queue[T]) Iter() iter.Seq[T] {
	return func(yield func(val T) bool) {
		for _, val := range s.data {
			if !yield(val) {
				return
			}
		}
	}
}

// IterAndPop 队列数据迭代消费器(消费数据)
//   - for v := range queueSync.IterAndPop() {}
func (s *Queue[T]) IterAndPop() iter.Seq[T] {
	return func(yield func(val T) bool) {
		for s.size > 0 {
			s.size--
			val := s.data[0]
			s.data = s.data[1:]
			if !yield(val) {
				return
			}
		}
	}
}

// Values 获取队列数据集切片
func (s *Queue[T]) Values() []T {
	return s.data
}

// Clear 清空队列数据
func (s *Queue[T]) Clear() {
	// 队列中元素已空
	if s.size == 0 {
		return
	}
	s.data = s.data[:0]
	s.size = 0
}

// MarshalJSON 序列化集合接口
func (s *Queue[T]) MarshalJSON() ([]byte, error) {
	return jsoner.Marshal(s.data)
}

// UnmarshalJSON 反序列化集合接口
func (s *Queue[T]) UnmarshalJSON(data []byte) error {
	items := []T{}
	err := jsoner.Unmarshal(data, &items)
	if err != nil {
		return err
	}
	s.data = items
	s.size = len(items)
	return nil
}
